package com.tuanzi.webtalk.websocket;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tuanzi.webtalk.domain.SocketMsg;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 雄关漫道真如铁，而今迈过从头越
 **/

@ServerEndpoint(value = "/websocket/{nickname}")
@Component
public class MyWebSocket {

    //用来存放用户对象的MyWebSocket对象
    private static CopyOnWriteArraySet<MyWebSocket> webSocketsSet = new CopyOnWriteArraySet<>();

    private static Map<String,Session> sessionMap = new HashMap<>();

    //获取用户的昵称
    private String nickname;

    //与客户连接对话，需要通过session给客户端发送消息
    private Session session;

    /**
     * 建立连接
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "nickname")String nickname){
        this.session = session;
        this.nickname = nickname;

        //加入到set集合中
        sessionMap.put(nickname,session);
        webSocketsSet.add(this);
        System.out.println("有新连接加入！当前在线人数为" + webSocketsSet.size());
        this.session.getAsyncRemote().sendText("欢迎登陆！当前在线人数为："+webSocketsSet.size());
    }

    /**
     * 关闭连接
     */
    @OnClose
    public void onClose(){
        //从set集合中删除
        webSocketsSet.remove(this);
        sessionMap.remove(this.nickname);
        System.out.println("有一连接关闭！当前在线人数为" + webSocketsSet.size());
    }

    /**
     *
     * @param message 收到的消息
     * @param session 聊天使用的载体session
     */
    @OnMessage
    public void onMessage(String message,Session session,@PathParam(value = "nickname")String nickname){
        //在控制台打印收到的消息
        System.out.println("来自客户端的消息"+message);

        //前台传回来的是json数据，，所以这里使用jackson转化为SocketMsg对象
        //然后通过socket的type判断是单聊还是群聊
        ObjectMapper objectMapper = new ObjectMapper();
        SocketMsg socketMsg;

        try {
            socketMsg = objectMapper.readValue(message,SocketMsg.class);

            String sender = socketMsg.getSender();
            String receiver = socketMsg.getReceiver();

            if (socketMsg.getType() == 1){
                //这个是一对一聊天

                socketMsg.setSender(session.getId()); //发送者
                Session senderSession = sessionMap.get(sender);
                Session receiverSession = sessionMap.get(receiver);

                //如果接受者不等于null
                if (receiverSession != null ){
                    //发送
                    //senderSession.getAsyncRemote().sendText(nickname+":"+socketMsg.getMessage());
                    receiverSession.getAsyncRemote().sendText("1:"+nickname+":"+socketMsg.getMessage());
                }else {
                    //发送给发送者
                    senderSession.getAsyncRemote().sendText("1:"+receiver+":"+"对不起，对方暂时不在线...");
                }
            }else {
                //群发消息
                sendEveryOne("0:"+receiver+":"+sender+":"+socketMsg.getMessage());
            }
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }


    /**
     * 出现错误的时候使用
     */
    @OnError
    public void onError(Session session,Throwable error){
        System.out.println("出现错误！！！");
        error.printStackTrace();
    }

    /**
     * 群发消息 每个人都发消息
     */
    public void sendEveryOne(String message){

        for (MyWebSocket socket : webSocketsSet) {
            //this.session.getBasicRemote().sendText(message);
            if (this != socket){
                //异步发送消息
                socket.session.getAsyncRemote().sendText(message);
            }
        }

    }




}
